package com.hilaver.dzmis.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.hilaver.dzmis.Constants;
import com.hilaver.dzmis.accesscontrol.AcAction;
import com.hilaver.dzmis.accesscontrol.AcUser;
import com.hilaver.dzmis.accesscontrol.AcUserAction;
import com.hilaver.dzmis.codetable.CtGender;
import com.hilaver.dzmis.dao.AcUserDAO;
import com.hilaver.dzmis.product.ProductIdentification;
import com.hilaver.dzmis.service.AbstractBaseService;
import com.hilaver.dzmis.service.IEntityService;
import com.hilaver.dzmis.util.SimpleObj2XML;

public class AcUserServiceImpl extends AbstractBaseService implements
		IEntityService {

	public static final String COLUMN_USER_NAME = "userName";
	
	public static final String COLUMN_REAL_NAME = "realName";
	
	public static final String COLUMN_CT_GENDER = "ctGender";
	
	public static final String COLUMN_AC_USER_ID = "acUser.id";
	
	public static final String COLUMN_AC_ACTION_ID = "acActionId";
	
	public static final String COLUMN_AC_ACTION_URL = "acActionUrl";
	
	public static final String COLUMN_AC_ACTION_NAME = "acActionName";
	
	public static final String COLUMN_AC_USER_ACTION_ID = "acUserActionId";
	
	public static final String DEFAULT_USER_NAME = "dpf";
	
	public static final String DEFAULT_PASSWORD = "dpf7541!";
	
	private CtServiceImpl ctService;
	
	protected AcUserDAO dao;

	public AcUserServiceImpl() {
		this.dao = new AcUserDAO();
		this.ctService = new CtServiceImpl();
	}
	
	public String edit(Object obj) throws Exception {
		AcUser acUser = (AcUser)obj;
		if(acUser.getId() == null){
			acUser.setIsValid("01");
			acUser.setIsMacEnable("01");
		}else{
			AcUser old = (AcUser)this.dao.get(
					AcUser.class.getName(), acUser.getId());
			acUser.setIsValid(old.getIsValid());
			acUser.setIsMacEnable(old.getIsMacEnable());
			if(acUser.getPhotoName() == null){
				acUser.setPhoto(old.getPhoto());
				acUser.setPhotoName(old.getPhotoName());
			}
			this.dao.getSession().evict(old);
		}
		this.dao.saveOrUpdate(obj);
		return "{success: true}";
	}
	
	@Override
	public String delete(int id) throws Exception {
		return super.delete(AcUser.class.getName(), id);
	}

	@Override
	public String get(int id) throws Exception {
		AcUser obj = (AcUser)this.dao.get(AcUser.class.getName(), id);
		StringBuffer xmlSB = new StringBuffer();
		xmlSB.append(Constants.XML_DOC_DEFINE);
		xmlSB.append(Constants.XML_ROOT_TAG[0]);
		xmlSB.append(Constants.XML_ITEM_TAG[0]);
		xmlSB.append(SimpleObj2XML.toXMLFragment(obj));
		xmlSB.append("<" + COLUMN_PHOTO_NAME + ">");
		if (obj.getPhotoName() == null || "".equals(obj.getPhotoName())) {
			xmlSB.append(NO_IMAGE_NAME);
		} else {
			writeFile(realFileDir + obj.getPhotoName(), obj.getPhoto());
			xmlSB.append(obj.getPhotoName());
		}
		xmlSB.append("</" + COLUMN_PHOTO_NAME + ">");
		xmlSB.append(Constants.XML_ITEM_TAG[1]);
		xmlSB.append(Constants.XML_ROOT_TAG[1]);
		return xmlSB.toString();
	}
	
	public String getWithDescription(int id)throws Exception {
		AcUser obj = (AcUser)this.dao.get(AcUser.class.getName(), id);
		StringBuffer xmlSB = new StringBuffer();
		xmlSB.append(Constants.XML_DOC_DEFINE);
		xmlSB.append(Constants.XML_ROOT_TAG[0]);
		xmlSB.append(Constants.XML_ITEM_TAG[0]);
		
		xmlSB.append("<" + COLUMN_CT_GENDER + ">");
		xmlSB.append(Constants.XML_CDATA[0]);
		xmlSB.append(this.ctService.getDescription(CtGender.class.getName(), obj.getCtGender(), locale));
		xmlSB.append(Constants.XML_CDATA[1]);
		xmlSB.append("</" + COLUMN_CT_GENDER + ">");
		
		xmlSB.append(SimpleObj2XML.toXMLFragment(obj));
		xmlSB.append("<" + COLUMN_PHOTO_NAME + ">");
		if (obj.getPhotoName() == null || "".equals(obj.getPhotoName())) {
			xmlSB.append(NO_IMAGE_NAME);
		} else {
			writeFile(realFileDir + obj.getPhotoName(), obj.getPhoto());
			xmlSB.append(obj.getPhotoName());
		}
		xmlSB.append("</" + COLUMN_PHOTO_NAME + ">");
		xmlSB.append(Constants.XML_ITEM_TAG[1]);
		xmlSB.append(Constants.XML_ROOT_TAG[1]);
		return xmlSB.toString();
	}

	@Override
	public String getAllPagination(int page, String sort, String order)
			throws Exception {
		return super.getAllPagination(AcUser.class.getName(), page, sort, order);
	}
	
	public String getAll(String sort, String order)
			throws Exception {
		return super.getAll(AcUser.class.getName(),sort, order);
	}
	
	public String getAllPagination(int page, String sort, String order, String[] filters)
			throws Exception {
		int offset = Constants.PAGE_SIZE * (page - 1);
		List<AcUser> objList = this.dao.getAllPagination(AcUser.class.getName(), offset,
				Constants.PAGE_SIZE, sort, order, filters);

		StringBuffer xmlSB = new StringBuffer();
		xmlSB.append(Constants.XML_DOC_DEFINE);
		xmlSB.append(Constants.XML_ROOT_TAG[0]);
		for (AcUser obj : objList) {
			xmlSB.append(Constants.XML_ITEM_TAG[0]);
			xmlSB.append(Constants.XML_INDEX_TAG[0]);
			xmlSB.append(++offset);
			xmlSB.append(Constants.XML_INDEX_TAG[1]);
			
			xmlSB.append("<" + COLUMN_PHOTO_NAME + ">");
			if (obj.getPhotoName() == null || "".equals(obj.getPhotoName())) {
				xmlSB.append(NO_IMAGE_NAME);
			} else {
				writeFile(realFileDir + obj.getPhotoName(), obj.getPhoto());
				xmlSB.append(obj.getPhotoName());
			}
			xmlSB.append("</" + COLUMN_PHOTO_NAME + ">");
			
			xmlSB.append("<" + COLUMN_CT_GENDER + ">");
			xmlSB.append(Constants.XML_CDATA[0]);
			xmlSB.append(this.ctService.getDescription(CtGender.class.getName(), obj.getCtGender(), locale));
			xmlSB.append(Constants.XML_CDATA[1]);
			xmlSB.append("</" + COLUMN_CT_GENDER + ">");
			
			xmlSB.append(SimpleObj2XML.toXMLFragment(obj));
			
			xmlSB.append(Constants.XML_ITEM_TAG[1]);
		}
		xmlSB.append(Constants.XML_CURRENT_PAGE_TAG[0]);
		xmlSB.append(page);
		xmlSB.append(Constants.XML_CURRENT_PAGE_TAG[1]);

		xmlSB.append(Constants.XML_ITEM_TOTAL_TAG[0]);
		xmlSB.append(this.dao.getCount(AcUser.class.getName(), filters));
		xmlSB.append(Constants.XML_ITEM_TOTAL_TAG[1]);

		xmlSB.append(Constants.XML_ROOT_TAG[1]);
		return xmlSB.toString();
	}
	
	public String isUserNameExist(Integer id, String userName) throws Exception{
		List<AcUser> userList = this.dao.findByProperty(AcUser.class.getName(), COLUMN_USER_NAME, userName);
		StringBuffer xmlSB = new StringBuffer();
		xmlSB.append(Constants.XML_DOC_DEFINE);
		xmlSB.append(Constants.XML_ROOT_TAG[0]);
		xmlSB.append(Constants.XML_ITEM_TAG[0]);
		if(userList.size() <= 0){
			xmlSB.append("false");
		}else{
			if(id != null && userList.get(0).getId().intValue() == id.intValue()){
				xmlSB.append("false");
			}else{
				xmlSB.append("true");
			}
		}
		xmlSB.append(Constants.XML_ITEM_TAG[1]);
		xmlSB.append(Constants.XML_ROOT_TAG[1]);
		return xmlSB.toString();
	}
	
	public String editAcUserAction(Integer userId, Integer[] actionIds, String isValid, String isMacEnable) throws Exception{
		AcUser acUser = (AcUser)this.dao.get(AcUser.class.getName(), userId);
		acUser.setIsValid(isValid);
		acUser.setIsMacEnable(isMacEnable);
		this.dao.saveOrUpdate(acUser);
		for(int i = 0; i < actionIds.length; i ++){
			if(this.dao.getAcUserActionListFrom(userId, actionIds[i]).size() == 0){
				AcAction acActoin = new AcAction();
				acActoin.setId(actionIds[i]);
				AcUserAction aua = new AcUserAction();
				aua.setAcUser(acUser);
				aua.setAcAction(acActoin);
				this.dao.saveOrUpdate(aua);
			}
		}
		
		return "{success: true}";
	}
	
	public String getAcUserActoinFilter(Integer userId, String sort, String order, String[] filters) throws Exception{
		if(filters == null){
			filters = new String[]{COLUMN_AC_USER_ID + " = '" + userId + "'"};
		}else{
			String[] temp = new String[filters.length + 1];
			temp[0] = COLUMN_AC_USER_ID + " = '" + userId + "'";
			for(int i = 1; i < temp.length; i ++){
				temp[i] = filters[i -1];
			}
			filters = temp;
		}
		List<AcUserAction> auaList = this.dao.getAcUserActionByListFilters(sort, order, filters);
		StringBuffer xmlSB = new StringBuffer();
		
		int offset = 0;
		xmlSB.append(Constants.XML_DOC_DEFINE);
		xmlSB.append(Constants.XML_ROOT_TAG[0]);
		for (AcUserAction aua : auaList) {
			xmlSB.append(Constants.XML_ITEM_TAG[0]);
			xmlSB.append(Constants.XML_INDEX_TAG[0]);
			xmlSB.append(++offset);
			xmlSB.append(Constants.XML_INDEX_TAG[1]);
			
			xmlSB.append(SimpleObj2XML.toXMLFragment(aua.getAcAction()));
			
			xmlSB.append("<" + COLUMN_AC_USER_ACTION_ID + ">");
			xmlSB.append(aua.getId());
			xmlSB.append("</" + COLUMN_AC_USER_ACTION_ID + ">");
			
			xmlSB.append(Constants.XML_ITEM_TAG[1]);
		}

		xmlSB.append(Constants.XML_CURRENT_PAGE_TAG[0]);
		xmlSB.append(Constants.XML_CURRENT_PAGE_TAG[1]);
		xmlSB.append(Constants.XML_ITEM_TOTAL_TAG[0]);
		xmlSB.append(Constants.XML_ITEM_TOTAL_TAG[1]);
		xmlSB.append(Constants.XML_ROOT_TAG[1]);
		return xmlSB.toString();
	}
	
	public String deleteAcUserAction(Integer id) throws Exception{
		return super.delete(AcUserAction.class.getName(), id);
	}
	
	public AcUser login(String userName, String pwd) throws Exception{
		AcUser acUser = null;
		List<AcUser> userList = this.dao.getAcUser(userName, pwd);
		if(userList.size() > 0){
			acUser = userList.get(0);
		}
		return acUser;
	}
	
	public List<AcAction> getAcActionListFrom(AcUser acUser) throws Exception{
		List<AcAction> aaList = new ArrayList<AcAction>();
		Set<AcUserAction> auaSet = acUser.getAcUserActions();
		for(AcUserAction aua : auaSet){
			aaList.add(aua.getAcAction());
		}
		return aaList;
	}
	
	public List<String> getActionUrlListFrom(AcUser acUser) throws Exception{
		List<String> urlList = new ArrayList<String>();
		Set<AcUserAction> auaSet = acUser.getAcUserActions();
		for(AcUserAction aua : auaSet){
			urlList.add(aua.getAcAction().getActionUrl());
		}
		return urlList;
	}
	
	public List<String> getActionNameListFrom(AcUser acUser) throws Exception{
		List<String> urlList = new ArrayList<String>();
		Set<AcUserAction> auaSet = acUser.getAcUserActions();
		for(AcUserAction aua : auaSet){
			if(Constants.LOCALE_TYPE_EN.equals(this.locale)){
				urlList.add(aua.getAcAction().getActionNameEn());
			}else if(Constants.LOCALE_TYPE_ZH.equals(this.locale)){
				urlList.add(aua.getAcAction().getActionNameCn());
			}else{
				urlList.add(aua.getAcAction().getActionNameFr());
			}
			
		}
		return urlList;
	}
	
	public AcAction getActionByURI(String uri) throws Exception{
		List<AcAction> actionList = this.dao.getAcAction(uri);
		if(actionList.size() > 0){
			return actionList.get(0);
		}else{
			return null;
		}
	}
	
	private static List<String> ACTION_URL_LIST = null;
	
	private void initActionUrlList() throws Exception{
		if(ACTION_URL_LIST == null){
			ACTION_URL_LIST = new ArrayList<String>();
			List<AcAction> acList = this.dao.getAll(AcAction.class.getName(), "actionUrl", Constants.ORDER_ASC);
			for(AcAction aa : acList){
				ACTION_URL_LIST.add(aa.getActionUrl());
			}
		}
	}
	
	public Boolean isInAcationList(String requestURI) throws Exception{
		initActionUrlList();
		return ACTION_URL_LIST.contains(requestURI);
	}

}



